package modele;

import java.io.Writer;
import java.rmi.server.UnicastRemoteObject;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;



public class DemandeImpl extends UnicastRemoteObject implements Demande {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	Dossier me;
	Date date;
	// les parcours dans l'ordre de preferences
	List<Fiche> fiches;

	public DemandeImpl(Dossier dos) throws Exception {
		me = dos;
		date = new Date();
		fiches = new ArrayList<Fiche>();
	}

	// pour faire un clone de la demande
	public DemandeImpl(Demande demande) throws Exception {
		me = demande.getDossier();
		date = demande.getDate();
		fiches = new ArrayList<Fiche>();
		for (Fiche fic : demande.getFiches())
			fiches.add(new FicheImpl(fic));
	}

	// les assesseurs
	public Dossier getDossier() throws Exception {
		return me;
	}
	public Date getDate() throws Exception {
		return date;
	}

	public List<Fiche> getFiches() throws Exception {
		return fiches;
	}

	/** retourne la fiche designee par indPar
	 *  apres l'avoir soit retrouvee, soit creee,
	 *  et apres l'avoir mis en position indPosition.
	 **/
	public Fiche getFiche(Integer indPar, int indPosition) throws Exception {
		Parcours par = me.getBd().getParcours(indPar);
		int ind = 0;
		for (Fiche fic : fiches) {
			if (fic.getParcours()==par){
				if (ind != indPosition)
					fiches.add(indPosition,fiches.remove(ind));
				return fic;
			}
			ind++;
		}
		Fiche fic = new FicheImpl(me, par);
		fiches.add(indPosition,fic);
		return fic;
	}

	public void setDate(Date d) throws Exception {
		date = d;
	}

	public Fiche addFiche(Parcours par) throws Exception {
		Fiche fic = new FicheImpl(me, par);
		fiches.add(fic);
		return fic;
	}

	public String getListeParcours() throws Exception {
		StringBuffer sb = new StringBuffer("[");
		int i = fiches.size();
		for (Fiche fic : fiches) {
			sb.append(fic.getParcours().getSigle());
			if(i>1)
				sb.append(", ");
			i--;
		}
		sb.append("]");
		return sb.toString();
	}
	
	public List<Parcours> getParcours() throws Exception {
		List<Parcours> l=new ArrayList<Parcours>();
		for (Fiche fic : fiches) {
			l.add(fic.getParcours());		
		}
		return l;
	}

	// les algos

	public boolean isValide() throws Exception {
		boolean valide = false;
		for (Fiche fic : fiches) {
			if(!valide) {
				boolean[] aux = fic.evaluer();
				valide |= aux[1];
			}
		}
		return valide;
	}

	/** restriction au bon nombre de fiches
	 *  numerotation des fiches
	 **/

	public void record(int nbFiches) throws Exception {
		while (fiches.size() > nbFiches)
			fiches.remove(fiches.size()-1);
		for (int i=0; i<nbFiches; i++)
			((Fiche)fiches.get(i)).setIndiceChoix(i);
	}

	public boolean equals(Demande dem) throws Exception {
		boolean idem = (me == dem.getDossier() &&
				date == dem.getDate() &&
				fiches.size() == dem.getFiches().size());
		if (idem)
			for (int i=0; i<fiches.size() & idem; i++) {
				Fiche fic = (Fiche)fiches.get(i);
				Fiche old = (Fiche)dem.getFiches().get(i);
				idem &= fic.equals(old);
			}
		return idem;
	}

	/** Mise a jour des liens Parcours et UEs
	 *  remove si b est faux
	 *  add si b est vrai
	 **/
	public void setLiensParUes(boolean b) throws Exception {
		for (Fiche fic : fiches)
			fic.setLiensParUes(b);
	}

	// les sorties

	public void imprimer(Writer file)
	throws Exception {
		Etudiant etu = me.getEtudiant();
		if (etu.getRedoublant())
			file.write(" R ");
		if (etu.getFormationContinue())
			file.write(" FC ");
		file.write(etu.getIdApoflux()+"&"+	etu.getNom()+"&"+etu.getPrenom()+"&"+etu.getEtablissementOrigine()+"&");
		if (me.getDemande().isValide())
			file.write("X&");
		else
			file.write("&");
		if (me.getEvaluation().isOK())
			file.write("X");
		file.write("&"+me.getEvaluation().getNoteDossier()+
				"&["+me.getFicheDemande().size()+"]"+
				me.getDemande().getListeParcours()+
				"&["+me.getPropositions().size()+"]");
		if (me.getProposition() != null)
			file.write(me.getProposition().getParcours()+
					"&"+me.getReponseCoupon()+"\\\\\n");
		else
			file.write("&\\\\\n");
	}

	public void imprimerCourrier(Writer file) throws Exception {
		file.write("\\begin{small}\n"+
				"\\begin{longtable}{ll}\n"+
				"\\caption*{}\\\\\n"+
				"ordre des UE au choix 1&ordre de l'UE au choix 2 \\\\\n"+
		"\\hline\n");
		for (Fiche fic : fiches)
			fic.imprimerCourrier(file);
		file.write("\\end{longtable}\n\\end{small}\n\n");
	}

	public void imprimerDossier(Writer file) throws Exception {
		int ind=1;
		for (Fiche fic : fiches) {
			fic.imprimerDossier(file,ind);
			ind++;
		}
	}

}
